"""
建造者模式是一种创建型设计模式，它允许你创建复杂对象的步骤与表示方式相分离。
建造者模式是一种创建型设计模式，它的主要目的是将一个复杂对象的构建过程与其表示相分离，从而可以创建具有不同表示形式的对象。
意图：
    将一个复杂的构建过程与其表示相分离，使得同样的构建过程可以创建不同的表示。
适用性：
    当一些基本部件不变，而其组合经常变化时。
结构：
    产品（Product）：要构建的复杂对象。产品类通常包含多个部分或属性。
    抽象建造者（Builder）：定义了构建产品的抽象接口，包括构建产品的各个部分的方法。
    具体建造者（Concrete Builder）：实现抽象建造者接口，具体确定如何构建产品的各个部分，并负责返回最终构建的产品。
    指导者（Director）：负责调用建造者的方法来构建产品，指导者并不了解具体的构建过程，只关心产品的构建顺序和方式。
"""
from abc import ABC, abstractmethod


# 产品
class Computer:
    def __init__(self):
        self.case = None
        self.motherboard = None
        self.cpu = None
        self.memory = None
        self.storage = None

    def __str__(self):
        return f'Computer: {self.case}, {self.motherboard}, {self.cpu}, {self.memory}, {self.storage}'


# 抽象建造者
class Builder(ABC):
    @abstractmethod
    def build_case(self):
        pass

    @abstractmethod
    def build_motherboard(self):
        pass

    @abstractmethod
    def build_cpu(self):
        pass

    @abstractmethod
    def build_memory(self):
        pass

    @abstractmethod
    def build_storage(self):
        pass

    @abstractmethod
    def get_computer(self):
        pass


# 具体建造者
class DesktopBuilder(Builder):
    def __init__(self):
        self.computer = Computer()

    def build_case(self):
        self.computer.case = 'Desktop Case'

    def build_motherboard(self):
        self.computer.motherboard = 'ATX Motherboard'

    def build_cpu(self):
        self.computer.cpu = 'Intel Core i7'

    def build_memory(self):
        self.computer.memory = '16GB DDR4 RAM'

    def build_storage(self):
        self.computer.storage = '512G SSD'

    def get_computer(self):
        return self.computer


# 指导者
class Director:
    def __init__(self, builder):
        self.builder = builder

    def construct_computer(self):
        self.builder.build_case()
        self.builder.build_motherboard()
        self.builder.build_cpu()
        self.builder.build_memory()
        self.builder.build_storage()

    def get_computer(self):
        return self.builder.get_computer()


if __name__ == '__main__':
    builder = DesktopBuilder()
    director = Director(builder)
    director.construct_computer()
    computer = director.get_computer()
    print(computer)
